﻿using DevExpress.Web.ASPxTreeView;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI.WebControls;
using System.Web.UI;
using EntryExit.Utils;

namespace EntryExit
{
    public partial class AttendanceCalendar : BasePage
    {
        public Dictionary<string, AttendanceInfo> CachedAttendanceData { get; set; }
        public Employee SelectedEmployee { get; set; }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (this.Master is MainMaster)
            {
                ((MainMaster)this.Master).MasterTreeViewNodeSelected += AttendanceCalendar_MasterTreeViewNodeSelected;
            }
        }

        void AttendanceCalendar_MasterTreeViewNodeSelected(object source, TreeViewNodeEventArgs e)
        {
            SelectedEmployee = EmployeeManagerContext.GetEmployee(SelectedEmployeeLPN);
            ReInitDataCache();
        }
        private void ReInitDataCache()
        {
            SelectedEmployee = EmployeeManagerContext.GetEmployee(SelectedEmployeeLPN);
            Session[SessionKeys.CACHED_ATTENDANCE_CALENDAR_DATA] = null;
            Session[SessionKeys.ATTENDANCE_CALENDAR_SHOWING_DATE] = DateTime.MinValue;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    DateTime dt = DateTime.Now.AddMonths(-11);
                    //attendanceCalendar.VisibleDate = new DateTime(DateTime.Now.Year, 1, 1);
                    attendanceCalendar.VisibleDate = new DateTime(dt.Year, dt.Month, dt.Day);

                    ReInitDataCache();
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Page : AttendanceCalendar.aspx.cs, Event : Page_Load", ex);
                ScriptManager.RegisterStartupScript(this, GetType(), "showalert", "alert('An internal error occured. Reload the tool and try again. If issue still persists, please report to your administrator..!');", true);
            }
        }

        private void CacheAttendanceData()
        {
            SelectedEmployee = EmployeeManagerContext.GetEmployee(SelectedEmployeeLPN);
            attendanceViewerPanel.HeaderText = "Attendance : " + SelectedEmployee.EmployeeName;
            Session[SessionKeys.ATTENDANCE_CALENDAR_SHOWING_DATE] = attendanceCalendar.VisibleDate;
            Session[SessionKeys.CACHED_ATTENDANCE_CALENDAR_DATA] = EmployeeManagerContext.GetEmployeeAttendanceWithLeave(attendanceCalendar.VisibleDate.AddYears(-1),
                attendanceCalendar.VisibleDate.AddYears(1), SelectedEmployee.CardHolderId, SelectedEmployee.LPN);
        }

        protected void attendanceCalendar_DayRender(object sender, DevExpress.Web.ASPxEditors.DayRenderEventArgs e)
        {
            try
            {
                if ((DateTime)Session[SessionKeys.ATTENDANCE_CALENDAR_SHOWING_DATE] != attendanceCalendar.VisibleDate)
                {
                    CacheAttendanceData();
                }

                AttendanceInfo attendanceInfo = GetAttendanceForDay(e.Day.DateTime);
                if (attendanceInfo != null)
                {
                    switch (attendanceInfo.StatusId)
                    
                    {
                        case UIConstants.IDENTIFIER_NO_LEAVE_DATA_AVAILABLE_SUN_OR_SAT:
                            e.Style.BackColor = Color.Gray;
                            if (attendanceInfo.TotalInTime.HasValue)
                            {
                                e.Day.ToolTip = String.Format("{0} : {1}", Convert.ToString(attendanceInfo.TotalInTime), attendanceInfo.LeaveInfo) + " " + attendanceInfo.Info;
                            }
                            else
                            {
                                e.Day.ToolTip = attendanceInfo.LeaveInfo + " " + attendanceInfo.Info;
                            }
                            break;
                        case UIConstants.IDENTIFIER_NO_DATA_OFFDAY:
                            e.Style.BackColor = Color.White;
                            if (attendanceInfo.TotalInTime.HasValue)
                            {
                                e.Day.ToolTip = String.Format("{0} : {1}", Convert.ToString(attendanceInfo.TotalInTime), attendanceInfo.LeaveInfo) + " " + attendanceInfo.Info;
                            }
                            else if (!string.IsNullOrEmpty(attendanceInfo.LeaveInfo))
                            {
                                e.Day.ToolTip = attendanceInfo.LeaveInfo + " " + attendanceInfo.Info;
                            }
                            else
                            {
                                e.Style.BackColor = Color.Red;
                                e.Day.ToolTip = "Unauthorised Absence";
                            }
                            break;
                        case UIConstants.IDENTIFIER_NO_DATA_BEFORE_DOJ:
                            e.Style.BackColor = Color.Aqua;
                            e.Day.ToolTip = "No data, Reason : Before DOJ";
                            break;
                        case UIConstants.IDENTIFIER_NO_ATTENDANCE_DATA_NO_LEAVE_DATA:
                            e.Style.BackColor = Color.Red;
                            e.Day.ToolTip = "Unauthorised Absence";
                            break;
                        case UIConstants.IDENTIFIER_DAY_AFTER_TODAY:
                            //Do Nothing
                            break;
                        case UIConstants.IDENTIFIER_NO_ATTENDANCE_DATA_AVAILABLE_IN_FUTURE:
                            //Do Nothing
                            break;
                        case UIConstants.IDENTIFIER_MARKED_AS_LEAVE:
                            e.Style.BackColor = Color.LightBlue;
                            //To show the hours worked on leave days
                            if (attendanceInfo.TotalInTime.HasValue)
                            {
                                e.Day.ToolTip = String.Format("{0} : {1}", Convert.ToString(attendanceInfo.TotalInTime), attendanceInfo.LeaveInfo) + " " + attendanceInfo.Info;
                            }
                            else
                            {
                                e.Day.ToolTip = attendanceInfo.LeaveInfo + " " + attendanceInfo.Info;
                            }
                            break;
                        case UIConstants.IDENTIFIER_LOW_WORK_HOURS:
                            e.Style.BackColor = Color.LightPink;
                            e.Day.ToolTip = Convert.ToString(attendanceInfo.TotalInTime) + " " + attendanceInfo.Info;
                            break;

                        case UIConstants.IDENTIFIER_LESSTHAN3_WORK_HOURS:
                            e.Style.BackColor = Color.Orange;
                            e.Day.ToolTip = Convert.ToString(attendanceInfo.TotalInTime) + " " + attendanceInfo.Info;
                            break;

                        case UIConstants.IDENTIFIER_NORMAL_WORK_HOURS:
                            e.Style.BackColor = Color.LightGreen;
                            e.Day.ToolTip = Convert.ToString(attendanceInfo.TotalInTime) + " " + attendanceInfo.Info;
                            break;
                        case UIConstants.IDENTIFIER_OVER_WORK_HOURS:
                            e.Style.BackColor = Color.Yellow;
                            e.Day.ToolTip = Convert.ToString(attendanceInfo.TotalInTime) + " " + attendanceInfo.Info;
                            break;
                        case UIConstants.IDENTIFIER_LOW_WORK_HOURS_HalfDay:
                            e.Style.BackColor = Color.GreenYellow;
                            e.Day.ToolTip = String.Format("{0} : {1}", Convert.ToString(attendanceInfo.TotalInTime), attendanceInfo.LeaveInfo) + " " + attendanceInfo.Info;
                            break;
                        default:
                            e.Style.BackColor = Color.Turquoise;
                            e.Day.ToolTip = "Unknown Attendance";
                            break;
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        private AttendanceInfo GetAttendanceForDay(DateTime attendanceDate)
        {
            string dayKey = attendanceDate.ToShortDateString();
            if (Session[SessionKeys.CACHED_ATTENDANCE_CALENDAR_DATA] == null)
            {
                return null;
            }
            else
            {
                if (SelectedEmployee.JoiningDate > attendanceDate)
                {
                    return new AttendanceInfo()
                    {
                        StatusId = UIConstants.IDENTIFIER_NO_DATA_BEFORE_DOJ
                    };
                }
                if (attendanceDate>DateTime.Now)
                {
                    return new AttendanceInfo()
                    {
                        StatusId = UIConstants.IDENTIFIER_DAY_AFTER_TODAY
                    };
                }
                if (CachedAttendanceData == null)
                {
                    CachedAttendanceData = Session[SessionKeys.CACHED_ATTENDANCE_CALENDAR_DATA] as Dictionary<string, AttendanceInfo>;
                }
                if (!CachedAttendanceData.ContainsKey(dayKey))
                {
                    if (attendanceDate < DateTime.Now)
                    {
                        return new AttendanceInfo()
                        {
                            StatusId = UIConstants.IDENTIFIER_NO_ATTENDANCE_DATA_NO_LEAVE_DATA
                        };
                    }
                    else
                    {
                        return new AttendanceInfo()
                        {
                            StatusId = UIConstants.IDENTIFIER_NO_ATTENDANCE_DATA_AVAILABLE_IN_FUTURE
                        };
                    }
                }
                else
                { 
                    /*If shift is not defined for an employee, except 2nd and 4th saturday all sundays and saturdays are off days*/
                    if (attendanceDate.Date.DayOfWeek == DayOfWeek.Saturday || attendanceDate.Date.DayOfWeek == DayOfWeek.Sunday)
                    {
                        AttendanceInfo dt = null;
                        if (CachedAttendanceData.ContainsKey(attendanceDate.ToShortDateString()))
                        {
                            dt = CachedAttendanceData[attendanceDate.ToShortDateString()];
                        }
                        if (dt != null)
                        {
                            if (dt.TotalInTime != null)
                            {
                                return CachedAttendanceData[attendanceDate.ToShortDateString()];
                            }

                        }
                        int j = 0;
                        if (attendanceDate.Date.DayOfWeek == DayOfWeek.Saturday && attendanceDate.Date.Month < 4 && attendanceDate.Date.Year <= 2014)
                        {
                            int currentDate = attendanceDate.Day;

                            for (int i = 1; i <= currentDate; i++)
                            {
                                DateTime Dt = new DateTime(attendanceDate.Year, attendanceDate.Month, i);
                                if (Dt.DayOfWeek == DayOfWeek.Saturday)
                                {
                                    j = j + 1;
                                }
                            }
                        }
                        if (!(j == 2 || j == 4) || attendanceDate.Date.DayOfWeek == DayOfWeek.Sunday)
                        {
                            return new AttendanceInfo()
                            {
                                StatusId = UIConstants.IDENTIFIER_NO_DATA_OFFDAY,
                                LeaveInfo =   LeaveLegend.OffDay.ToString()
                            };
                        }
                        
                    }
                }
                return CachedAttendanceData[attendanceDate.ToShortDateString()];
            }
        }
    }
}